package org.wen.soft.asm.handler;

import org.objectweb.asm.Type;

import java.util.ArrayList;
import java.util.List;
import java.util.function.Function;

public class SignatureType {


    List<String> parameterClassNameList = new ArrayList<>();
    List<String> parameterSimpleNameList = new ArrayList<>();



    String returnClassName;
    String returnSimpleName;

    // 方法、类的泛型T信息
    String broadType;

    public SignatureType(String typeSignature) {
        if (typeSignature == null || typeSignature.isEmpty()) {
            return;
        }
        // 处理方法、类的<>泛型声明
        if (typeSignature.indexOf("<") == 0) {
            int index = typeSignature.indexOf(">");
            broadType = typeSignature.substring(1, index);
            typeSignature = typeSignature.substring(index + 1);
        }

        // 处理方法参数
        if (typeSignature.indexOf("(") == 0) {
            // 参数
            String parametersSignature = typeSignature.substring(1,  typeSignature.indexOf(")"));
            List<String> parameterSignatureList = new ArrayList<>();
            splitSignature(parameterSignatureList, parametersSignature, ';');
            for (String parameterSignature : parameterSignatureList) {
                parameterClassNameList.add(className(parameterSignature));
                parameterSimpleNameList.add(simpleName(parameterSignature));
            }
            // 返回值
            typeSignature = typeSignature.substring(typeSignature.indexOf(")") + 1);
        }
        // 单类型、返回值类型
        returnClassName = className(typeSignature);
        returnSimpleName = simpleName(typeSignature);
    }

    public String getClassName(){
        return returnClassName;
    }

    public String getSimpleName(){
        return returnSimpleName;
    }

    public List<String> getParameterClassNames(){
        return parameterClassNameList;
    }

    public List<String> getParameterSimpleNames(){
        return parameterSimpleNameList;
    }


    private String classTypeName(String signature){
        if (signature.indexOf("T") == 0) {
            return signature.substring(1, signature.length() - 1);
        }
        if (signature.contains("+")) {
            signature = signature.replace("+", "");
        }
        return Type.getType(signature).getClassName();
    }


    private String className(String typeSignature){
        return handlerSignature(typeSignature, ';', this::classTypeName);
    }

    private String simpleName(String typeSignature){
        return handlerSignature(typeSignature, ';', signature -> SimpleUtil.simpleName(classTypeName(signature)));
    }

    /**
     * 泛型分割， 使用<...>;进行分割
     * @param items 分割结果
     * @param signature 泛型文本
     */
    private static void splitSignature(List<String> items, String signature, Character character) {
        byte[] bytes = signature.getBytes();
        int leftCount = 0;
        int rightCount = 0;
        for (int i = 0; i < bytes.length; i++) {
            if (bytes[i] == '<') {
                leftCount++;
            }
            if (bytes[i] == '>') {
                rightCount++;
            }
            if (leftCount == rightCount) {
                // 基本类型分割: 当前字符是基本类型，且是左侧无字符或为分隔符
                if (byteIsBasicType(bytes[i]) && (i == 0 || bytes[i - 1] == ';')) {
                    items.add(signature.substring(i, i + 1));
                    splitSignature(items, signature.substring(i + 1), character);
                    break;
                }

                int nextIndex = i + 1;
                if (nextIndex < bytes.length  && bytes[i + 1] == character) {
                    items.add(signature.substring(0, nextIndex + 1));
                    nextIndex = nextIndex + 1;
                    if (nextIndex < bytes.length) {
                        splitSignature(items, signature.substring(nextIndex), character);
                        break;
                    }
                }
            }

        }
    }

    /**
     * 字符是否是基本类型 > VZCBSIFJD [86, 90, 67, 66, 83, 73, 70, 74, 68]
     */
    private static boolean byteIsBasicType(byte b) {
        byte[] bytes = "VZCBSIFJD".getBytes();
        for (byte aByte : bytes) {
            if (aByte == b) {
                return true;
            }
        }
        return false;
    }
    /**
     * 处理Signature
     * @param signature Signature文本
     * @param delimiter 分割符号
     * @param handler 处理单元，传递单元处理前的信息、返回处理后的信息
     * @return 处理完毕整合的结果
     */
    private static String handlerSignature(String signature, Character delimiter, Function<String, String> handler) {
        if (!signature.contains("<")) {
            return handler.apply(signature);
        }
        int innerStart = signature.indexOf("<");
        String outerSignature = signature.substring(0, innerStart) + delimiter;
        String outerClassName = handler.apply(outerSignature);
        String innerSignature = signature.substring(innerStart + 1, signature.length() - 2);
        List<String> innerSignatureList = new ArrayList<>();
        splitSignature(innerSignatureList, innerSignature, delimiter);
        List<String> innerClassNameList = new ArrayList<>();
        for (String innerSignatureItem : innerSignatureList) {
            innerClassNameList.add(handlerSignature(innerSignatureItem, delimiter, handler));
        }
        return outerClassName + "<" + String.join(", ", innerClassNameList) + ">";
    }

}
